/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package conf2.ui;

import java.awt.Color;
import javax.swing.JComponent;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.JTextComponent;

/**
 *
 * @author Administrator
 */
public class InputValidator implements DocumentListener
{

    public static int MAX_NAME_LENGTH = 16;
    public static final Restriction NAME_RESTRICTION = new NameRestriction();
    public static final Restriction IP_RESTRICTION = new IPRestriction();
    public static final Restriction PORT_RESTRICTION = new PortRestriction();

    public static interface Restriction
    {

        boolean isValid(String fieldContents);
    }
    private final JTextComponent comp;
    private final JComponent toEnableWhenOK;
    private final Restriction restriction;
    private static final Color okColor = new JTextArea().getBackground(),  failColor = Color.PINK;

    private InputValidator(JTextComponent comp, JComponent toEnableWhenOK)
    {
        this.comp = comp;
        this.toEnableWhenOK = toEnableWhenOK;
        if (comp != null) {
            comp.getDocument().addDocumentListener(this);
        }
        this.restriction = null;
    }

    private InputValidator(JTextComponent comp, JComponent toEnableWhenOK, Restriction restriction)
    {
        this.comp = comp;
        this.toEnableWhenOK = toEnableWhenOK;
        this.restriction = restriction;
        if (comp != null) {
            comp.getDocument().addDocumentListener(this);
        }
    }

    public static void bind(JTextComponent comp, JComponent toEnableWhenOK)
    {
        new InputValidator(comp, toEnableWhenOK);
    }

    public static void bind(JTextComponent comp, JComponent toEnableWhenOK, Restriction restriction)
    {
        new InputValidator(comp, toEnableWhenOK, restriction);
    }

    public boolean isValid()
    {
        if (restriction == null) {
            return true;
        }
        return restriction.isValid(comp.getText());
    }

    private void doValidation()
    {
        if (comp == null) {
            return;
        }
        String text = comp.getText();
        if (restriction != null) {
            if (restriction.isValid(text)) {
                comp.setBackground(okColor);
                if (toEnableWhenOK != null) {
                    toEnableWhenOK.setEnabled(true);
                }
            } else {
                comp.setBackground(failColor);
                if (toEnableWhenOK != null) {
                    toEnableWhenOK.setEnabled(false);
                }
            }
        }

    }

    public void insertUpdate(DocumentEvent e)
    {
        doValidation();
    }

    public void removeUpdate(DocumentEvent e)
    {
        doValidation();
    }

    public void changedUpdate(DocumentEvent e)
    {
        doValidation();
    }
}

class NameRestriction implements InputValidator.Restriction
{

    public boolean isValid(String fieldContents)
    {
        int l = fieldContents.trim().length();
        return 0 < l && l <= InputValidator.MAX_NAME_LENGTH;
    }
}

class IPRestriction implements InputValidator.Restriction
{

    public boolean isValid(String fieldContents)
    {
        String s = fieldContents.trim().toLowerCase();
        if (s.equals("localhost")) {
            return true;
        }

        if (!Character.isDigit(s.charAt(s.length() - 1))) {
            return false;
        }
        String[] groups = s.split("\\.");
        if (groups.length != 4) {
            return false;
        }
        for (String group : groups) {
            try {
                int i = Integer.parseInt(group);
                if (i < 0 && i > 255) {
                    return false;
                }
            } catch (NumberFormatException e) {
                return false;
            }
        }
        return true;
    }
}

class PortRestriction implements InputValidator.Restriction
{

    public boolean isValid(String fieldContents)
    {
        try {
            int port = Integer.parseInt(fieldContents);
            return port > 1023 && port < 65536;
        } catch (NumberFormatException e) {
            return false;
        }
    }
}
